home *** CD-ROM | disk | FTP | other *** search
- // =================================================================
- // Dbarray.cpp
- // =================================================================
- // Harold Kasperink / John Dekker
- // Dr. Dobb's Journal 1997
- // =================================================================
- // Multithreaded Database Array Singleton class
- // =================================================================
- #include <iostream.h>
- #include "dbarray.h"
-
- // Fill singleton array with initial value
- CArrayDbase * CArrayDbase::g_pDbArray = 0;
- CMutex CArrayDbase::g_mtxArray;
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::CArrayDbase
- ////////////////////////////////////////////////////////////////////
- // Constructor
- ////////////////////////////////////////////////////////////////////
- CArrayDbase::CArrayDbase(int nNrConnections, const char *szUsr, const char *szPsswd, const char *szDB)
- {
- m_nNrDbases = 0;
- m_pszUsr = 0;
- m_pszPsswd = 0;
- m_pszDb = 0;
- m_nCurCon = 0;
- m_bPrint = FALSE;
- memset(m_nDbUsage, 0, MAX_NR_DBASES*sizeof(int));
-
- // Check if database array object allready there
- if (g_pDbArray != 0)
- return;
-
- // Check parameter
- if (nNrConnections < 1)
- nNrConnections = 1;
- if (nNrConnections > MAX_NR_DBASES)
- nNrConnections = MAX_NR_DBASES;
-
- ConnectInfo(szUsr, szPsswd, szDB);
-
- // Create databases
- for (int i=0; i<nNrConnections; i++) {
- m_pDbases[i] = new CDbase;
- if (m_pDbases[i] == 0) {
- // Not succeedeed
- cout << "No Connections\n";
- }
- m_nNrDbases = nNrConnections;
- }
-
- // Create database threads
- for (i=0; i<nNrConnections; i++) {
- m_pDbases[i]->ConnectInfo(m_pszUsr, m_pszPsswd, m_pszDb);
- m_pDbases[i]->Create();
- }
-
- // Everything OK
- g_pDbArray = this;
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::~CArrayDbase
- ////////////////////////////////////////////////////////////////////
- // Destructor
- ////////////////////////////////////////////////////////////////////
- CArrayDbase::~CArrayDbase()
- {
- DeleteConnectInfo();
- m_bPrint = FALSE;
-
- if (this == g_pDbArray) {
- Lock();
- g_pDbArray = 0;
- Unlock();
- }
-
- for (int i=0; i<m_nNrDbases; i++) {
- if (m_pDbases[i] != 0)
- delete m_pDbases[i];
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::ConnectInfo
- ////////////////////////////////////////////////////////////////////
- // Set connect information strings
- ////////////////////////////////////////////////////////////////////
- void CArrayDbase::ConnectInfo(const char *szUsr, const char *szPsswd, const char *szDB)
- {
- DeleteConnectInfo();
-
- if (szUsr != 0)
- m_pszUsr = strdup(szUsr);
-
- if (szPsswd != 0)
- m_pszPsswd = strdup(szPsswd);
-
- if (szDB != 0)
- m_pszDb = strdup(szDB);
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::DeleteConnectInfo
- ////////////////////////////////////////////////////////////////////
- // free connect information strings
- ////////////////////////////////////////////////////////////////////
- void CArrayDbase::DeleteConnectInfo()
- {
- if (m_pszUsr != 0)
- delete m_pszUsr;
-
- if (m_pszPsswd != 0)
- delete m_pszPsswd;
-
- if (m_pszDb != 0)
- delete m_pszDb;
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::~ReserveDbase
- ////////////////////////////////////////////////////////////////////
- // Get free database connection from array object
- ////////////////////////////////////////////////////////////////////
- CDbase *CArrayDbase::ReserveDbase()
- {
- // If no database array object
- if (g_pDbArray == 0)
- return 0;
-
- Lock();
-
- // Get dbases from database array object
- CDbase ** pDbases = g_pDbArray->m_pDbases;
- int nNrDbases = g_pDbArray->m_nNrDbases;
- int * pCurCon = &g_pDbArray->m_nCurCon;
- int * nDbUsage = g_pDbArray->m_nDbUsage;
-
- // Loop for find a free database connection
- while (TRUE) {
- for (int i=0; i<nNrDbases; i++) {
- // Database array object is delete in mean-time
- if (g_pDbArray == 0)
- return 0;
-
- // Find free database
- if (pDbases[i]->TryLock()) {
- nDbUsage[i] += 1;
- Unlock();
- return pDbases[i];
- }
- }
-
- // All connections are occupied, see take inuse one
- CDbase *pDb = pDbases[*pCurCon];
- nDbUsage[*pCurCon] += 1;
-
- // Increase next inuse counter
- *pCurCon += 1;
- if (*pCurCon >= nNrDbases)
- *pCurCon = 0;
-
- Unlock();
- pDb->Lock();
- return pDb;
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::~ReleaseDbase
- ////////////////////////////////////////////////////////////////////
- // Release allocated database
- ////////////////////////////////////////////////////////////////////
- void CArrayDbase::ReleaseDbase(CDbase &dbase)
- {
- // If no database array object
- if (g_pDbArray == 0)
- return;
-
- Lock();
-
- // Get dbases from database array object
- CDbase ** pDbases = g_pDbArray->m_pDbases;
- int nNrDbases = g_pDbArray->m_nNrDbases;
- int * nDbUsage = g_pDbArray->m_nDbUsage;
-
- // Search for database
- for (int i=0; i<nNrDbases; i++) {
- // Find free database
- if (pDbases[i] == &dbase) {
- nDbUsage[i] -= 1;
- dbase.Unlock();
- Unlock();
- return;
- }
- }
- Unlock();
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::Lock
- ////////////////////////////////////////////////////////////////////
- void CArrayDbase::Lock()
- {
- g_mtxArray.Lock();
- }
-
- ////////////////////////////////////////////////////////////////////
- // CArrayDbase::UnLock
- ////////////////////////////////////////////////////////////////////
- void CArrayDbase::Unlock()
- {
- g_mtxArray.Unlock();
- }
-
-